﻿#include "chinese.h"
/*! ************************************************************
 * \file
 * \brief 提供CPU、内存、硬件、网卡等系统信息的获取方法
 *
 * \authors 林胜勇
 *
 * \date
 * \verbatim
 * 变更记录：
 * 2023-11-30，林胜勇:
 *   创建文件
 * \endverbatim
 ****************************************************************/

#pragma once

#include <QString>
#include <string>
#include <vector>

namespace cppc {
/// 网络信息
struct NetInfo {
    std::string name; /*网络接口名称*/
    std::string ip;   /*网口IP*/
    std::string mac;  /*网口MAC地址*/
    float rxSpeed;    /*下行速度，字节/秒*/
    float txSpeed;    /*上行速度，字节/秒*/
};

/// CPU信息
struct CpuInfo {
    float user;   // 用户使用率，单位%
    float system; // 系统内核使用率，单位%
    float usage;  // 总使用率，单位%
};

/// 内存信息
struct RamInfo {
    float usage;         // 内存使用率，单位%
    long long totalSize; /* 总内存，单位：字节*/
    long long freeSize;  /* 剩余内存，单位：字节 */
};

/// 磁盘分区信息
struct DiskPartitionInfo {
    std::string path;    // 分区路径
    std::string type;    // 文件系统类型
    float usage;         // 磁盘使用率，单位%
    long long totalSize; /* 总分区大小，单位：字节*/
    long long freeSize;  /* 剩余空间大小，单位：字节*/
};

/// CPU瞬时信息
struct CpuOccupy {
    std::string name;
    unsigned int user;   // 用户级进程运行时间
    unsigned int nice;   // 优先级较低的进程运行时间
    unsigned int system; // 内核级进程运行时间
    unsigned int idle;   // CPU空闲时间
};

/// 网卡信息
struct NetInterfaceInfo {
    std::string name; /*网络接口名称*/
    std::string ip;   /*网口IP*/
    std::string mac;  /*网口MAC地址*/
};

/// 网卡上下行实时累计流量
struct NetInterfaceFlow {
    bool valid;        // 数据是否有效
    std::string name;  // 网卡名称
    int64_t txBytes;   // 累计发送字节数
    int64_t rxBytes;   // 累计接收字节数
    int64_t tickCount; // 开机相对时间，用来计算网速
    int64_t timeStamp; // UTC时间，用来显示
    NetInterfaceFlow() :
        valid(false), name(""), txBytes(0), rxBytes(0), tickCount(0), timeStamp(0) {
    }
};

/// 收发数据包结构体
struct NetInterfaceSpeed {
    bool valid;       // 数据是否有效
    std::string name; // 网卡名称
    long rxSpeed;     /*下行速度，字节/秒*/
    long txSpeed;     /*上行速度，字节/秒*/
    NetInterfaceSpeed() :
        valid(false), name(""), rxSpeed(0), txSpeed(0) {
    }
};

class SystemUtil {
public:
    /// 读取磁盘分区信息
    /// \param path 关注的分区路径
    static DiskPartitionInfo getDiskPartitionInfo(const std::string &path);

    /// 获取内存信息
    static RamInfo getRamInfo();

public:
    /// 获取CPU瞬时信息
    static CpuOccupy getCpuOccupy();

    /// 计算CPU使用率
    /// \param begin 第1次CPU瞬时信息
    /// \param end 第2次CPU瞬时信息
    static CpuInfo calCpuInfo(const CpuOccupy &begin, const CpuOccupy &end);

public:
    /// 获取网卡列表
    static std::vector<NetInterfaceInfo> getNetInterfaceList();

    /// 获取网卡信息
    static NetInterfaceInfo getNetInterface(const std::string &netName);

    /// 获取网卡实时累计流量
    /// \param netName 网卡名称
    /// \return <发送字节，接收字节，统计时间>
    static NetInterfaceFlow getNetInterfaceFlow(const std::string &netName);

    /// 获取所有网卡的实时上下行流量
    /// \return 网卡对应的实时流量
    static std::vector<NetInterfaceFlow>
    getNetInterfaceFlow(const std::vector<NetInterfaceInfo> &netList);

    /// 计算网卡上下行网速
    static NetInterfaceSpeed calNetInterfaceSpeed(const NetInterfaceFlow &begin,
                                                  const NetInterfaceFlow &end);

    /// 获取硬盘序列号
    static QString getDiskSerialNumber();
};

} // namespace cppc
